<script lang="ts">
	import { onMount } from 'svelte'
	import { codemirror, withCodemirrorInstance } from '@neocodemirror/svelte'
	import { javascript } from '@codemirror/lang-javascript'
	import { Pane, Splitpanes } from 'svelte-splitpanes'
	import {
		Tabs,
		TabItem,
		Table,
		TableBody,
		TableBodyCell,
		TableBodyRow,
		TableHead,
		TableHeadCell,
		ToolbarGroup,
		Label,
		Input,
		Button,
		InputAddon,
		ButtonGroup,
		Checkbox,
	} from 'flowbite-svelte'

	import type { GetParams, IpcResponse, TradeStrategy, UpdateParams } from '$lib/bindings'
	import * as commands from '$lib/commands'
	import type { TradeStrategyIndicator } from '$lib/bindings/TradeStrategyIndicator'
	import type { TradeStrategyMaLine } from '$lib/bindings/TradeStrategyMaLine'

	export let tradeStrategy: TradeStrategy

	let consoleElement: HTMLDivElement // Bind this to your console div
	let strategy_name = tradeStrategy.name
	let kl_window = tradeStrategy.kl_window
	let script_value = tradeStrategy.script ?? ''

	// This acts a readonly store. $ notation works here
	const cmInstance = withCodemirrorInstance()

	$: console.log(
		'codemirror cmInstance:',
		$cmInstance.view,
		$cmInstance.value,
		$cmInstance.extensions,
	)

	async function update_trade_strategy() {
		console.log('update_trade_strategy strategy_name=', strategy_name)
		console.log('update_trade_strategy kl_window=', kl_window)
		if (tradeStrategy && tradeStrategy.id) {
			// Call your API to update visibility
			let args: UpdateParams<TradeStrategy> = {
				id: tradeStrategy.id.id.String,
				data: {
					klt: tradeStrategy?.klt,
					seqno: tradeStrategy?.seqno,
					name: strategy_name,
					kl_window: Number(kl_window),
					id: null,
					desc: null,
					script_verified: null,
					script: null,
					indicators: null,
					is_online: null,
					last_updated: null,
					malines: null,
				},
			}
			try {
				let rs = await commands.update_trade_strategy(args)
				// Optionally, handle success response here
				console.log(`(update_trade_strategy) Succeed to update trade_strategy  for ID ${tradeStrategy.id?.id.String} .`)
				if (rs.result) {
					consoleElement.textContent = `Update Name OK: ${tradeStrategy.id?.id.String}`
				} else if (rs.error) {
					consoleElement.textContent = rs.error.message
				}
			} catch (error) {
				// Handle any errors that occur during the API call
				console.error(
					`(update_trade_strategy) Failed to update trade_strategy for ID ${tradeStrategy.id?.id.String}:`,
					error,
				)

				consoleElement.textContent = JSON.stringify(error)
			}
		}
	}

	async function update_trade_strategy_script() {
		console.log(`update_trade_strategy_script: `, $cmInstance.value)
		if (tradeStrategy && tradeStrategy.id) {
			// Call your API to update visibility
			let args: UpdateParams<TradeStrategy> = {
				id: tradeStrategy.id?.id.String,
				data: {
					klt: tradeStrategy?.klt,
					seqno: tradeStrategy?.seqno,
					script: $cmInstance.value,
					script_verified: false,
					id: null,
					kl_window: null,
					name: null,
					desc: null,
					indicators: null,
					is_online: null,
					last_updated: null,
					malines: null,
				},
			}
			try {
				let rs = await commands.update_trade_strategy(args)
				// Optionally, handle success response here
				console.log(
					`(update_trade_strategy_script) Succeed to update trade_strategy script for ID ${tradeStrategy.id?.id.String} .`,
				)
				if (rs.result) {
					consoleElement.textContent = `Update Script OK: ${tradeStrategy.id?.id.String}`
				} else if (rs.error) {
					consoleElement.textContent = rs.error.message
				}
			} catch (error) {
				// Handle any errors that occur during the API call
				console.error(
					`(update_trade_strategy_script) Failed to update trade_strategy script for ID ${tradeStrategy.id?.id.String}:`,
					error,
				)

				consoleElement.textContent = JSON.stringify(error)
			}
		}
	}

	async function verify_trade_strategy() {
		console.log('click verify_trade_strategy 验证')
		consoleElement.textContent = `Step 1. 开始验证脚本 for ID: ${tradeStrategy.id?.id.String} ... `
		if (tradeStrategy && tradeStrategy.id) {
			// Call your API to update visibility
			let args: GetParams = {
				id: tradeStrategy.id.id.String,
			}
			try {
				let rs = await commands.verify_trade_strategy(args)
				// Optionally, handle success response here
				console.log(
					`(verify_trade_strategy) Succeed to verify trade_strategy script for ID ${tradeStrategy.id?.id.String} , rs=`,
					rs,
				)
				if (rs.result) {
					consoleElement.textContent =
						consoleElement.textContent + `  Step 2. 验证脚本： ${rs.result.data}`
				} else if (rs.error) {
					consoleElement.textContent =
						consoleElement.textContent + `  Step 2. 验证脚本： ${rs.error.message}`
				}
			} catch (error) {
				// Handle any errors that occur during the API call
				console.error(
					`(verify_trade_strategy) Failed to verify trade_strategy script for ID ${tradeStrategy.id?.id.String}:`,
					error,
				)

				consoleElement.textContent = JSON.stringify(error)
			}
		}
	}

	async function publish_trade_strategy() {
		if (tradeStrategy && tradeStrategy.id) {
			// Call your API to update visibility
			let args: GetParams = {
				id: tradeStrategy.id.id.String,
			}
			console.log('click publish_trade_strategy 发布 args=', args)
			consoleElement.textContent = `策略发布中...`
			try {
				let rs = await commands.publish_trade_strategy(args)
				// Optionally, handle success response here

				console.log('click publish_trade_strategy 发布 rs=', rs)
				if (rs.result) {
					let rd = rs.result.data
					consoleElement.textContent = `策略发布成功 ${tradeStrategy.id.id.String}`
				} else if (rs.error) {
					consoleElement.textContent = rs.error.message
				}
			} catch (error) {
				// Handle any errors that occur during the API call
				console.error(
					`(publish_trade_strategy) Failed to publish trade_strategy script for ID ${tradeStrategy.id?.id.String}:`,
					error,
				)

				consoleElement.textContent = JSON.stringify(error)
			}
		}
	}

	async function update_strategy_indicator(tsi: TradeStrategyIndicator, e: Event) {
		const target = e.target as HTMLInputElement // Cast event target to HTMLInputElement
		const isChecked = target.checked
		tsi.is_used = isChecked // Update the strategy's checked state
		console.log(`Checkbox with id ${tsi.gk} is now:`, isChecked)
		if (tradeStrategy && tradeStrategy.id) {
			// You can perform any update logic here based on the checkbox state
			let args: UpdateParams<TradeStrategyIndicator> = {
				id: tradeStrategy.id?.id.String,
				data: {
					gk: tsi.gk,
					is_used: isChecked,
				},
			}
			consoleElement.textContent = `策略使用的指标更新中...`
			try {
				let rs = await commands.update_trade_strategy_indicator(args)
				// Optionally, handle success response here

				if (rs.result) {
					let strategy: TradeStrategy = rs.result.data

					consoleElement.textContent = `策略使用的指标更新成功  ${strategy.name}`
				} else if (rs.error) {
					consoleElement.textContent = `策略使用的指标更新失败 ${rs.error.message}`
				}
			} catch (error) {
				// Handle any errors that occur during the API call
				console.error(
					`(update_strategy_indicator) Failed to update trade_strategy_indicator for ID ${tradeStrategy.id?.id.String}:`,
					error,
				)

				consoleElement.textContent = JSON.stringify(error)
			}
		}
	}

	async function update_strategy_maline(tsml: TradeStrategyMaLine, e: Event): Promise<void> {
		const target = e.target as HTMLInputElement // Cast event target to HTMLInputElement
		const isChecked = target.checked
		tsml.is_used = isChecked // Update the strategy's checked state
		console.log(`Checkbox with id ${tsml.gk}.${tsml.period} is now:`, isChecked)
		if (tradeStrategy && tradeStrategy.id) {
			// You can perform any update logic here based on the checkbox state
			let args: UpdateParams<TradeStrategyMaLine> = {
				id: tradeStrategy.id?.id.String,
				data: {
					gk: tsml.gk,
					period: tsml.period,
					is_used: isChecked,
				},
			}
			consoleElement.textContent = `策略使用的均线更新中...`

			try {
				let rs = await commands.update_trade_strategy_maline(args)
				// Optionally, handle success response here

				if (rs.result) {
					let strategy = rs.result.data
					consoleElement.textContent = `策略使用的均线更新成功 ${strategy.name}`
				} else if (rs.error) {
					consoleElement.textContent = `策略使用的均线更新失败 ${rs.error.message}`
				}
			} catch (error) {
				// Handle any errors that occur during the API call
				console.error(
					`(update_strategy_indicator) Failed to update update_trade_strategy_maline for ID ${tradeStrategy.id?.id.String}:`,
					error,
				)

				consoleElement.textContent = JSON.stringify(error)
			}
		}
	}
</script>

<div class=" w-full h-svh overflow-auto bg-gray-200">
	<div class="flex py-2 bg-orange-200">
		<div class="grow flex">
			<ButtonGroup class="w-full rounded-none">
				<InputAddon class="rounded-none whitespace-nowrap">
					K线: {tradeStrategy?.klt}, 序号: {tradeStrategy?.seqno}, 策略名称:
				</InputAddon>
				<Input
					class="rounded-none"
					id="input-addon-lg"
					type="text"
					bind:value={strategy_name}
					on:change={(e) => update_trade_strategy()}
				/>
			</ButtonGroup>
			<ButtonGroup class="w-full rounded-none">
				<InputAddon class="rounded-none whitespace-nowrap">K线窗口:</InputAddon>
				<Input
					class="rounded-none"
					id="input-addon-lg"
					type="number"
					bind:value={kl_window}
					on:change={(e) => update_trade_strategy()}
				/>
			</ButtonGroup>
		</div>

		<!-- <button
			on:click={() => console.log('click 放弃')}
			class="flex-none rounded-none mx-2 p-1 min-w-20 bg-blue-600 border-solid border-2 border-gray-500 text-white"
		>
			放弃编辑
		</button> -->
		<button
			on:click={() => verify_trade_strategy()}
			class="flex-none rounded-none mx-2 p-1 min-w-20 bg-blue-600 border-solid border-2 border-gray-500 text-white"
		>
			验证脚本
		</button>
		{#if tradeStrategy && tradeStrategy.script_verified}
			<button
				on:click={() => publish_trade_strategy()}
				class="flex-none rounded-none mx-2 p-1 min-w-20 bg-blue-600 border-solid border-2 border-gray-500 text-white"
			>
				发布策略
			</button>
		{:else}
			<button
				class="flex-none rounded-none mx-2 p-1 min-w-20 bg-gray-300 border-solid border-2 border-gray-500 text-white"
			>
				发布策略
			</button>
		{/if}
	</div>
	<Splitpanes style="height: 100%" pushOtherPanes={false} horizontal>
		<Pane size={80}>
			<Splitpanes style="height: 100%" pushOtherPanes={false}>
				<Pane size={60}>
					<div
						class="w-full h-full min-h-96 bg-white text-black"
						use:codemirror={{
							value: script_value,
							lang: javascript({ typescript: true }),
							instanceStore: cmInstance,
						}}
						on:codemirror:textChange={() => {
							update_trade_strategy_script()
						}}
					/>
				</Pane>
				<Pane size={25}>
					<div class="w-full bg-orange-400">Edit TradeStrategy help</div>
					<div>1. 脚本中最好使用不超过4个指标，否则在TBotChart中不能展示</div>
					<div>2. 脚本中最好使用不超过9条均线，否则在TBotChart中不能展示</div>
				</Pane>
				<Pane size={15}>
					<Splitpanes style="height: 100%" pushOtherPanes={false} horizontal>
						<Pane size={50}>
							<div class="bg-blue-400">Used Indicators(Up to 4)</div>
							<div class="w-full h-full min-h-96 overflow-auto">
								<Table hoverable={true}>
									<TableHead defaultRow={false}>
										<tr
											class="bg-gray-400 text-left text-xs font-medium text-gray-900 uppercase sticky top-0 z-10"
										>
											<TableHeadCell padding="pr-2" class="text-nowrap">使用</TableHeadCell>
											<TableHeadCell padding="pr-2" class="text-nowrap">指标</TableHeadCell>
										</tr>
									</TableHead>
									<TableBody
										tableBodyClass="divide divide-solid divide-green-200 text-xs text-gray-500"
									>
										{#if tradeStrategy && tradeStrategy.indicators}
											{#each tradeStrategy.indicators as tsi, index (tsi.gk)}
												<TableBodyRow
													class="divide-x divide-slate-200 hover:bg-green-400"
													tabindex={index}
												>
													<TableBodyCell tdClass="pr-1 w-12">
														<Checkbox
															bind:checked={tsi.is_used}
															on:change={(e) => update_strategy_indicator(tsi, e)}
														></Checkbox>
													</TableBodyCell>
													<TableBodyCell tdClass="pr-1">{tsi.gk}</TableBodyCell>
												</TableBodyRow>
											{/each}
										{/if}
										<TableBodyRow>
											<TableBodyCell colspan="2">Bottom Line</TableBodyCell>
										</TableBodyRow>
									</TableBody>
								</Table>
							</div>
						</Pane>

						<Pane size={50}>
							<div class="bg-blue-400">Used MaLines(Up to 9)</div>
							<div class="w-full h-full min-h-96 overflow-auto">
								<Table hoverable={true}>
									<TableHead defaultRow={false}>
										<tr
											class="bg-gray-400 text-left text-xs font-medium text-gray-900 uppercase sticky top-0 z-10"
										>
											<TableHeadCell padding="pr-2" class="text-nowrap">使用</TableHeadCell>
											<TableHeadCell padding="pr-2" class="text-nowrap">均线名称</TableHeadCell>
											<TableHeadCell padding="pr-2" class="text-nowrap">均线周期</TableHeadCell>
										</tr>
									</TableHead>
									<TableBody
										tableBodyClass="divide divide-solid divide-green-200 text-xs text-gray-500"
									>
										{#if tradeStrategy && tradeStrategy.malines}
											{#each tradeStrategy.malines as tsml, index (tsml.gk + '_' + tsml.period)}
												<TableBodyRow
													class="divide-x divide-slate-200 hover:bg-green-400"
													tabindex={index}
												>
													<TableBodyCell tdClass="pr-1 w-12">
														<Checkbox
															bind:checked={tsml.is_used}
															on:change={(e) => update_strategy_maline(tsml, e)}
														></Checkbox>
													</TableBodyCell>
													<TableBodyCell tdClass="pr-1">{tsml.gk}</TableBodyCell>
													<TableBodyCell tdClass="pr-1">{tsml.period}</TableBodyCell>
												</TableBodyRow>
											{/each}
										{/if}
										<TableBodyRow>
											<TableBodyCell colspan="3">Bottom Line</TableBodyCell>
										</TableBodyRow>
									</TableBody>
								</Table>
							</div>
						</Pane>
					</Splitpanes>
				</Pane>
			</Splitpanes>
		</Pane>
		<Pane size={20}>
			<div id="consoleElement" bind:this={consoleElement} class="w-full h-36 bg-slate-200">
				Script verifcation result
			</div>
		</Pane>
	</Splitpanes>
</div>
